home *** CD-ROM | disk | FTP | other *** search
- unit PaletteTweaking;
-
- interface
-
- implementation
-
- uses
- CommonStuff, ExtCtrls, Menus, SysUtils, Dialogs, Classes, Windows,
- CommCtrl, Messages, Forms;
-
- type
- TPaletteTweaking = class(TObject)
- private
- FTimer: TTimer;
- FMultilineOption,
- FHotTrackOption,
- FButtonsOption,
- FToolsOptions: TMenuItem;
- FOldOnResize,
- FOldToolsOptionsOnClick: TNotifyEvent;
- protected
- procedure DoConfigurePaletteClick(Sender: TObject);
- procedure DoPaletteOptions(Sender: TObject);
- procedure DoTimer(Sender: TObject);
- procedure DoResize(Sender: TObject);
- procedure UpdateIDESize(OldRowCount: Integer);
- procedure SetMultiLine(Value: Boolean);
- procedure SetHotTrack(Value: Boolean);
- procedure SetButtons(Value: Boolean);
- public
- constructor Create;
- destructor Destroy; override;
- end;
-
- resourcestring
- SMultiLine = '&Multiline'; //Multiline toggle option
- SHotTrack = '&Hot tracking'; //Hot-tracking toggle option
- SButtons = '&Buttons instead of tabs'; //Tabs as buttons toggle option
-
- const
- SToolsOptions = 'ToolsOptionsItem'; //Tools | Environment Options...
- SToolsOptionsOnClick = 'ToolsOptions'; //OnClick handler for above
- SMainFormOnResize = 'WindowResize'; //OnResize handler for main form
- SMsgDlgClass = 'TMessageForm'; //Class name of a MessageDlg form
- //Registry strings
- SRegMultiLine = 'Multi-line Component Palette';
- SRegButtons = 'Tabs As Buttons';
- SRegHotTrack = 'Hot Tracking';
- SRegTabHeight = 'Tab Height';
-
- constructor TPaletteTweaking.Create;
- begin
- inherited Create;
- //Make sure there is an options menu - bear in mind
- //that the other options code might not be being used
- Stuff.AddOptionsItem;
- //Set up the hot track, multiline and buttons menu items
- FMultilineOption := NewItem(SMultiLine, 0,
- Stuff.Ini.ReadBool(SRegSection, SRegMultiLine,
- Stuff.FTabControl.MultiLine),
- True, DoPaletteOptions, 0, '');
- FHotTrackOption := NewItem(SHotTrack, 0,
- Stuff.Ini.ReadBool(SRegSection, SRegHotTrack,
- Stuff.FTabControl.HotTrack),
- True, DoPaletteOptions, 0, '');
- FButtonsOption := NewItem(SButtons, 0,
- Stuff.Ini.ReadBool(SRegSection, SRegButtons,
- GetWindowLong(Stuff.FTabControl.Handle, gwl_Style) and
- tcs_Buttons <> 0),
- True, DoPaletteOptions, 0, '');
- //All 3 items use the same handler - Tag distinguishes them
- FMultilineOption.Tag := 1;
- FHotTrackOption.Tag := 2;
- FButtonsOption.Tag := 3;
- //Insert the option menu items
- Stuff.FOptions.Add(FMultilineOption);
- Stuff.FOptions.Add(FHotTrackOption);
- Stuff.FOptions.Add(FButtonsOption);
- //To help avoid flickering, we chain into an IDE event handler
- //This may cause problems if someone else chains on to it
- //afterwards, and then we are deleted. The later chainer will
- //be referring to dead code -> AV time
- //Note that we do check to see if the event is already
- //chained and warn the user if so
-
- //Find Tools | Environment Options...
- FToolsOptions := GetComponent(Application.MainForm, SToolsOptions,
- SGenericError + SToolsOptions) as TMenuItem;
- //Save old OnClick handler
- FOldToolsOptionsOnClick := FToolsOptions.OnClick;
- //Warn user if event was already chained
- TestChainedEventHandler(TMethod(FOldToolsOptionsOnClick).Code,
- Application.MainForm.MethodAddress(SToolsOptionsOnClick));
- //Replace Delphi's event handler with our own
- FToolsOptions.OnClick := DoConfigurePaletteClick;
- //Trap IDE form resizing - save old OnResize event
- FOldOnResize := Application.MainForm.OnResize;
- //Warn user if event was already chained
- TestChainedEventHandler(TMethod(FOldOnResize).Code,
- Application.MainForm.MethodAddress(SMainFormOnResize));
- //Replace Delphi's event handler with our own
- Application.MainForm.OnResize := DoResize;
-
- //Set the palette properties as dictated by registry
- //This should really be done here, but the multi-line stuff
- //can't manage to make the IDE window larger when
- //Delphi is starting so we do it in a timer event instead
- FTimer := TTimer.Create(nil);
- FTimer.OnTimer := DoTimer;
- FTimer.Interval := 500;
- end;
-
- destructor TPaletteTweaking.Destroy;
- begin
- //Save option states
- Stuff.Ini.WriteBool(SRegSection, SRegMultiLine, FMultilineOption.Checked);
- Stuff.Ini.WriteBool(SRegSection, SRegHotTrack, FHotTrackOption.Checked);
- Stuff.Ini.WriteBool(SRegSection, SRegButtons, FButtonsOption.Checked);
- //Tidy up timer
- FTimer.Free;
- //Get rid of customisations from IDE
- SetMultiLine(False);
- SetHotTrack(False);
- SetButtons(False);
- //Unchain the chained event handlers
- if Assigned(FToolsOptions) then
- FToolsOptions.OnClick := FOldToolsOptionsOnClick;
- if Assigned(FOldOnResize) then
- Application.MainForm.OnResize := FOldOnResize;
- inherited Destroy
- end;
-
- procedure TPaletteTweaking.DoConfigurePaletteClick(Sender: TObject);
- begin
- //To avoid the excess flicker of the multi-line
- //component palette, we'll try turning it off when
- //it would normally flicker
- SetMultiLine(False);
- //Chain onto old OnClick handler
- if (Sender = FToolsOptions) and
- Assigned(FOldToolsOptionsOnClick) then
- FOldToolsOptionsOnClick(Sender);
- //Set back old value
- SetMultiLine(FMultilineOption.Checked);
- end;
-
- procedure TPaletteTweaking.DoPaletteOptions(Sender: TObject);
- begin
- //Toggle options as requested
- with Sender as TMenuItem do
- begin
- Checked := not Checked;
- case Tag of
- 1: SetMultiLine(Checked);
- 2: SetHotTrack(Checked);
- 3: SetButtons(Checked);
- end
- end
- end;
-
- procedure TPaletteTweaking.DoTimer(Sender: TObject);
- begin
- //This triggers shortly after Delphi starts
- //(or whenever this package is initialised)
-
- //Only perform the settings if there is no error
- //message (such as a package load failure). Errors
- //are shown with MessageDlgs which are of type
- //TMessageForm. Let the timer keep running until
- //it's gone so the settings do actually take effect
- if not (Screen.ActiveForm.ClassName = SMsgDlgClass) then
- begin
- FTimer.Enabled := False;
- SetMultiLine(FMultilineOption.Checked);
- SetHotTrack(FHotTrackOption.Checked);
- //Don't need to call this as both the
- //previous routines do it anyway
- //SetButtons(FButtonsOption.Checked);
- end
- end;
-
- procedure TPaletteTweaking.DoResize(Sender: TObject);
- var
- OldRows: Integer;
- begin
- //IDE is being resized - how many tab rows are there right now?
- OldRows := Stuff.FTabControl.Perform(tcm_GetRowCount, 0, 0);
- //Chain onto old OnResize event
- if Assigned(FOldOnResize) then
- FOldOnResize(Sender);
- //Resync component palette's multiline situation
- UpdateIDESize(OldRows);
- end;
-
- procedure TPaletteTweaking.UpdateIDESize(OldRowCount: Integer);
- var
- Rows: Integer;
- begin
- //If component palette has decided to have
- //a different number of lines then...
- Rows := Stuff.FTabControl.Perform(tcm_GetRowCount, 0, 0) - OldRowCount;
- if Rows = 0 then Exit;
- //Need more/less room for the tab rows
- //Store how much we increased by, so we can
- //decrease the same amount when asked to
- Stuff.FTabControl.Height := Stuff.FTabControl.Height +
- Rows * Stuff.Ini.ReadInteger(SRegSection,
- SRegTabHeight, Stuff.FTabControl.TabHeight);
- //Tell main form to resize according to tab control's height
- with Application.MainForm do
- PostMessage(Handle, wm_Size,
- size_Restored, MakeLong(Width, Height));
- end;
-
- procedure TPaletteTweaking.SetMultiLine(Value: Boolean);
- var
- OldRows: Integer;
- begin
- OldRows := Stuff.FTabControl.Perform(tcm_GetRowCount, 0, 0);
- Stuff.FTabControl.MultiLine := Value;
- //If MultiLine property changes, the window gets
- //recreated so we need to set button status back as appropriate
- //since we hacked that option - it ain't a property
- SetButtons(FButtonsOption.Checked);
- UpdateIDESize(OldRows);
- end;
-
- procedure TPaletteTweaking.SetHotTrack(Value: Boolean);
- begin
- Stuff.FTabControl.HotTrack := Value;
- //If HotTrack property changes, the window gets
- //recreated so we need to set buttons back as appropriate
- //since we hacked that option - it ain't a property
- SetButtons(FButtonsOption.Checked)
- end;
-
- procedure TPaletteTweaking.SetButtons(Value: Boolean);
- var
- Style: Longint;
- begin
- //TTabControl/TPageControl doesn't make
- //buttons facility available as a property
- Style := GetWindowLong(Stuff.FTabControl.Handle, gwl_Style);
- if Value then
- Style := Style or tcs_Buttons
- else
- Style := Style and not tcs_Buttons;
- //Set desired window style
- SetWindowLong(Stuff.FTabControl.Handle, gwl_Style, Style);
- end;
-
- var
- PaletteTweakingObject: TPaletteTweaking;
-
- initialization
- try
- PaletteTweakingObject := TPaletteTweaking.Create
- except
- on E: Exception do
- ShowMessage(SSetupError + ': ' + E.Message)
- end
- finalization
- PaletteTweakingObject.Free
- end.
-